package org.dmikis.jmmengine.models;

import java.util.concurrent.*;

/**
 * @author dmikis
 * @version 0.1
 * 
 * Concurrent implementation of EquationSolver
 */
public class ConcurrentEquationSolver extends EquationSolver implements Callable<Double> {

    /**
     * Creates new <code>ConcurrentEquationSolver</code> object and starts
     * computational thread immediately.
     * 
     * @param func
     * @param accuracy
     */
    public ConcurrentEquationSolver(DifferentiableFunction func, double accuracy) {
	super(func, accuracy);
	this.computationTask = new FutureTask<Double>(this);
	Thread t = new Thread(computationTask);
	t.start();
    }

    @Override
    public Double call() throws EquationUnsolvedException {
	return new Double(super.getResult());
    }

    /**
     * Get value of solution. This method blocks thread
     * if it's called until computational thread finished.
     * 
     * @return value of results
     * @throws EquationUnsolvedException if iterative process keeps continuing more than 50000 cycles.
     */
    public double getResult() throws EquationUnsolvedException {
	try {
	    return computationTask.get().doubleValue();
	}
	catch (ExecutionException e) {
	    throw (EquationUnsolvedException) e.getCause();
	}
	catch (InterruptedException e) {
	    e.printStackTrace();
	}
	return 0;
    }

    private FutureTask<Double> computationTask;
}
